package cn.com.jonpad.demo.controller;

import cn.com.jonpad.demo.domain.User;
import cn.com.jonpad.demo.repository.UserRepository;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.validation.Valid;

/**
 * @author Jon Chan
 * @date 2019/5/13 21:57
 */
@RestController
@RequestMapping("user")
@AllArgsConstructor
public class UserController {

    private final UserRepository userRepository;

    @GetMapping
    public Flux<User> getAll() {
        return userRepository.findAll();
    }

    @GetMapping("{id}")
    public Mono<ResponseEntity<User>> getOne(@PathVariable("id") String id) {
        return userRepository.findById(id)
                .map(user -> new ResponseEntity<>(user, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    /**
     * 以SSE形式多次返回数据
     *
     * @return
     */
    @GetMapping(value = "stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> getStreamAll() {
        return userRepository.findAll();
    }

    @PostMapping()
    public Mono<User> getStreamAll(@Valid @RequestBody User user) {
        return userRepository.save(user);
    }

    @DeleteMapping("{id}")
    public Mono<ResponseEntity<Void>> getStreamAll(@PathVariable("id") String id) {

        // 无返回值，无法判断是否删除成功
        // Mono<Void> voidMono = userRepository.deleteById(id);

        return userRepository.findById(id)
                // 需要操作数据并且返回Mono，使用flatMap
                // 不操作数据只是做个转换，使用map
                .flatMap(user -> userRepository.delete(user)
                        .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK))))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @PutMapping("{id}")
    public Mono<ResponseEntity<User>> update(@Valid @PathVariable("id") String id, @RequestBody User user) {
        return userRepository.findById(id)
                // 操作数据
                .flatMap(u -> {
                    u.setAge(user.getAge());
                    u.setName(user.getName());
                    return this.userRepository.save(u);
                })
                // 转换数据
                .map(u -> new ResponseEntity<User>(u, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }
}
